package com.qys.livesMall.product.service.impl;

import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qys.livesMall.common.constants.Constants;
import com.qys.livesMall.common.exception.QysException;
import com.qys.livesMall.common.result.R;
import com.qys.livesMall.framework.utils.SecurityUtils;
import com.qys.livesMall.product.entity.H2ProductGoodsinfo;
import com.qys.livesMall.product.entity.H2ProductSku;
import com.qys.livesMall.product.entity.H2ProductSkuAttribute;
import com.qys.livesMall.product.entity.ProductSkuAttributeOptions;
import com.qys.livesMall.product.mapper.H2ProductSkuMapper;
import com.qys.livesMall.product.model.dto.AddAttrOptions;
import com.qys.livesMall.product.model.dto.DelAttrOptions;
import com.qys.livesMall.product.model.dto.EditProductSku;
import com.qys.livesMall.product.model.vo.AddAttrOptionsVO;
import com.qys.livesMall.product.service.H2ProductGoodsinfoService;
import com.qys.livesMall.product.service.H2ProductSkuAttributeService;
import com.qys.livesMall.product.service.H2ProductSkuService;
import com.qys.livesMall.product.service.ProductSkuAttributeOptionsService;
import jakarta.annotation.Resource;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author gmx
 * @since 2023-05-17
 */
@Service
public class H2ProductSkuServiceImpl extends ServiceImpl<H2ProductSkuMapper, H2ProductSku> implements H2ProductSkuService {

    @Resource
    private H2ProductGoodsinfoService goodsInfoService;
    @Resource
    private H2ProductSkuAttributeService attributeService;
    @Resource
    private ProductSkuAttributeOptionsService optionsService;
    @Resource
    private H2ProductSkuService skuService;
    @Resource
    private H2ProductSkuMapper skuMapper;
    @Override
    @Transactional(rollbackFor={Exception.class})
    public boolean decount(Long id, int num) {
        int count = skuMapper.decount(id, num);
        return count<=0?false:true;
    }

    @Override
    public Integer getBySpuId(Long spuId) {
        LambdaQueryWrapper<H2ProductSku> queryWrapper=new LambdaQueryWrapper<>();
        queryWrapper.select(H2ProductSku::getNum);
        queryWrapper.eq(H2ProductSku::getStatus,1);
        queryWrapper.eq(H2ProductSku::getSpuId,spuId);
        List<H2ProductSku> h2ProductSkus=list(queryWrapper);
        if (CollectionUtils.isEmpty(h2ProductSkus)){
            return 0;
        }
        return h2ProductSkus.stream().mapToInt(H2ProductSku::getNum).sum();
    }

    @Override
    public List<H2ProductSku> listBySpuId(Long spuId) {
        LambdaQueryWrapper<H2ProductSku> queryWrapper=new LambdaQueryWrapper<>();
        queryWrapper.eq(H2ProductSku::getSpuId,spuId);
        return list(queryWrapper);
    }

    @Override
    public AddAttrOptionsVO add(AddAttrOptions attrOptions){
        //检查商品
        H2ProductGoodsinfo goodsInfo=goodsInfoService.getById(attrOptions.getSpuId());
        if (goodsInfo==null){
            throw new QysException("product.spu.null");
        }
        if(StringUtils.isEmpty(attrOptions.getOptionsName())){
            return null;
        }
        List<H2ProductSkuAttribute> attributes= attributeService.getBySpuId(goodsInfo.getId());
        List<Long> attrIds=attributes.stream().map(H2ProductSkuAttribute::getId).collect(Collectors.toList());
        List<ProductSkuAttributeOptions> options=optionsService.listByAttrIds(attrIds);
        if(CollectionUtils.isEmpty(options)){
            options=new ArrayList<>();
        }
        //检查名称是否存在
        TreeMap<Long,List<ProductSkuAttributeOptions>> optionsMap=options.stream().collect(Collectors.groupingBy(ProductSkuAttributeOptions::getAttrId,TreeMap::new, Collectors.toList()));
        List<ProductSkuAttributeOptions> exists=null;
        if (optionsMap.size()>0) {
            List<ProductSkuAttributeOptions> allOp=optionsMap.get(attrOptions.getAttrId());
            if (CollectionUtils.isEmpty(allOp)){
                exists=null;
            }else {
                exists = optionsMap.get(attrOptions.getAttrId()).stream().filter(o -> Objects.equals(o.getName(), attrOptions.getOptionsName())).collect(Collectors.toList());
            }
        }
        if (CollectionUtils.isNotEmpty(exists)){
            ProductSkuAttributeOptions option=exists.get(0);
            //获取所有sku
            List<H2ProductSku> skus=skuService.listBySpuId(attrOptions.getSpuId());
            if (CollectionUtils.isEmpty(skus)){
               skus=new ArrayList<>();
            }
            List<H2ProductSku> ups=new ArrayList<>();
            for (H2ProductSku sku:skus){
                Map<String,Object> attrMap=JSONObject.parseObject(sku.getSkuAttribute(), HashMap.class);
                for(String attrId:attrMap.keySet()){
                    if (!Objects.equals(attrId,attrOptions.getAttrId().toString())){
                        continue;
                    }
                    String value=String.valueOf(attrMap.get(attrId));
                    if (!Objects.equals(String.valueOf(option.getId()),value)){
                        continue;
                    }
                    //状态检验
                    Map<Long,ProductSkuAttributeOptions> optionsMapTemp=options.stream().collect(Collectors.toMap(ProductSkuAttributeOptions::getId,v->v));
                    Integer status=getStatus(String.valueOf(option.getId()),attrMap,optionsMapTemp);
                    sku.setStatus(status);
                    sku.setNum(0);
                    ups.add(sku);
                }
            }

            skuService.updateBatchById(ups);
            //options设置有效
            option.setEnable(Constants.YesNoInt.YES);
            optionsService.updateById(option);
            AddAttrOptionsVO vo=new AddAttrOptionsVO();
            vo.setSkus(skus);
            vo.setOption(option);
            return vo;
        }
        //新增
        //构建option
        ProductSkuAttributeOptions option=new ProductSkuAttributeOptions();
        option.setAttrId(attrOptions.getAttrId());
        option.setName(attrOptions.getOptionsName());
        option.setEnable(Constants.YesNoInt.YES);
        optionsService.save(option);
        //检查构建条件
        List<ProductSkuAttributeOptions> addOptions= optionsMap.get(attrOptions.getAttrId());
        if (addOptions==null){
            addOptions=new ArrayList<>();
        }
        addOptions.add(option);
        optionsMap.put(attrOptions.getAttrId(),addOptions);


        //确保每个规格都有属性
        for(H2ProductSkuAttribute attribute:attributes){
            if (CollectionUtils.isEmpty(optionsMap.get(attribute.getId()))){
                //存在没有值的规格，不建商品
                AddAttrOptionsVO vo=new AddAttrOptionsVO();
                vo.setOption(option);
                return vo;
            }
        }
        //建立sku
        //名称
        List<H2ProductSku> adds=new ArrayList<>();
        for(Long attrId:optionsMap.keySet()){
            if (Objects.equals(attrId,attrOptions.getAttrId())){
                ProductSkuAttributeOptions temp=option;
                if (CollectionUtils.isEmpty(adds)){
                    H2ProductSku sku=new H2ProductSku();
                    sku.setStatus(1);
                    sku.setName(goodsInfo.getName()+temp.getName());
                    JSONObject obj=new JSONObject();
                    obj.put(temp.getAttrId().toString(),temp.getId());
                    sku.setSkuAttribute(obj.toJSONString());
                    sku.setStatus(getStatus(sku,temp));
                    adds.add(sku);
                }else {
                    for(H2ProductSku sku:adds) {
                        sku.setName(sku.getName() + "," + temp.getName());
                        JSONObject obj = JSONObject.parseObject(sku.getSkuAttribute());
                        obj.put(temp.getAttrId().toString(), temp.getId());
                        sku.setSkuAttribute(obj.toJSONString());
                        sku.setStatus(getStatus(sku,temp));
                    }
                }
           }else {
                List<ProductSkuAttributeOptions> optionsList= optionsMap.get(attrId);
                List<H2ProductSku> skuTemps=new ArrayList<>();
                for(ProductSkuAttributeOptions temp2:optionsList){
                    if (CollectionUtils.isNotEmpty(adds)) {
                        for (H2ProductSku oldSku : adds) {
                            H2ProductSku sku=new H2ProductSku();
                            sku.setStatus(1);
                            sku.setName(oldSku.getName() + "," + temp2.getName());
                            JSONObject obj=JSONObject.parseObject(oldSku.getSkuAttribute());
                            obj.put(temp2.getAttrId().toString(),temp2.getId());
                            sku.setSkuAttribute(obj.toJSONString());
                            sku.setStatus(getStatus(sku,temp2));
                            skuTemps.add(sku);
                        }
                    }else {
                        H2ProductSku sku=new H2ProductSku();
                        sku.setStatus(1);
                        sku.setName(goodsInfo.getName()+" "+temp2.getName());
                        JSONObject obj=new JSONObject();
                        obj.put(temp2.getAttrId().toString(),temp2.getId());
                        sku.setSkuAttribute(obj.toJSONString());
                        sku.setStatus(getStatus(sku,temp2));
                        skuTemps.add(sku);
                    }
                }
                adds=skuTemps;
           }

        }
        //添加其他信息
        for(H2ProductSku sku:adds){
            sku.setNum(0);
            sku.setPrice(goodsInfo.getPrice());
            sku.setSpuId(attrOptions.getSpuId());
            sku.setCategoryId(goodsInfo.getCategoryTwoId());
            sku.setCreateTime(LocalDateTime.now());
            sku.setCreateBy(SecurityUtils.getUsername());
        }
        skuService.saveBatch(adds);
        AddAttrOptionsVO vo=new AddAttrOptionsVO();
        vo.setSkus(adds);
        vo.setOption(option);
        List<H2ProductSku> skus=skuService.listBySpuId(attrOptions.getSpuId());
        vo.setSkus(skus);
        return vo;
    }

    private Integer getStatus(H2ProductSku sku,ProductSkuAttributeOptions option){
        if (!Objects.equals(sku.getStatus(),1)){
            return sku.getStatus();
        }
        if (Objects.equals(option.getEnable(), Constants.YesNoInt.YES)){
            return 1;
        }
        return 2;
    }

    private Integer getStatus(Object newOptionId,Map<String,Object> attrs,Map<Long,ProductSkuAttributeOptions> optionsMap){
        Integer status=1;
        for(Object optionId:attrs.values()){
            if (Objects.equals(String.valueOf(optionId),newOptionId)){
                continue;
            }
            ProductSkuAttributeOptions option=optionsMap.get(Long.valueOf(String.valueOf(optionId)));
            if (Objects.equals(option.getEnable(), Constants.YesNoInt.NO)){
                status=2;
            }
        }
        return status;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void upd(EditProductSku editSku) {
        if (editSku==null||editSku.getId()==null){
            throw new QysException("product.spu.null");
        }
        H2ProductSku sku=getById(editSku.getId());
        if (sku==null){
            throw new QysException("goods.does.not.exist");
        }
        sku.setNum(editSku.getNum());
        sku.setPrice(editSku.getPrice());
        sku.setName(editSku.getName());
        sku.setImage(editSku.getImage());
        updateById(sku);
        //更新库存
        Integer num=getBySpuId(sku.getSpuId());
        H2ProductGoodsinfo spu=goodsInfoService.getById(sku.getSpuId());
        spu.setNum(num);
        goodsInfoService.updateById(spu);
    }

    @Override
    public List<H2ProductSku> del(DelAttrOptions attrOptions) {
        //检查商品
        H2ProductGoodsinfo goodsInfo=goodsInfoService.getById(attrOptions.getSpuId());
        if (goodsInfo==null){
            throw new RuntimeException("product.spu.null");
        }
        ProductSkuAttributeOptions option=optionsService.getById(attrOptions.getOptionId());
        option.setEnable(Constants.YesNoInt.NO);
        optionsService.updateById(option);

        List<H2ProductSku> skus=skuService.listBySpuId(attrOptions.getSpuId());
        if (CollectionUtils.isEmpty(skus)){
            return null;
        }
        List<H2ProductSku> ups=new ArrayList<>();
        for (H2ProductSku sku:skus){
            Map<String,Object> attrMap=JSONObject.parseObject(sku.getSkuAttribute(), HashMap.class);
            for(String attrId:attrMap.keySet()){
                if (!Objects.equals(attrId,option.getAttrId().toString())){
                    continue;
                }
                String value=String.valueOf(attrMap.get(attrId));
                if (!Objects.equals(String.valueOf(option.getId()),value)){
                    continue;
                }
                sku.setStatus(2);
                ups.add(sku);
            }
        }

        skuService.updateBatchById(skus);
        //更新库存
        Integer num=getBySpuId(goodsInfo.getId());
        goodsInfo.setNum(num);
        goodsInfoService.updateById(goodsInfo);
        skus=skuService.listBySpuId(attrOptions.getSpuId());
        return skus;
    }
}
